﻿/*
 * Author: Alexander Sjösten
 */

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
using System.IO;
using Final_Project.CustomerData;

namespace Final_Project
{
    /// <summary>
    /// This class represents the FileManager.
    /// It saves Customers to disk by serializing them.
    /// It loads Customers from disk by deserializing them.
    /// </summary>
    class FileManager
    {
        // Local variables
        Stream stream;
        BinaryFormatter binFor;

        /// <summary>
        /// Default constructor that creates a FileManager object
        /// and sets up a BinaryFormatter.
        /// </summary>
        public FileManager()
        {
            binFor = new BinaryFormatter();
        }

        /// <summary>
        /// Method to serialize a list of customers by iterating
        /// through and serialize each object independently
        /// </summary>
        /// <param name="customers">The list of customers to serialize</param>
        public void SerializeCustomers(List<Customer> customers)
        {
            stream = File.Open("CustomersInfo.info", FileMode.Create);

            foreach (Customer cust in customers)
            {
                binFor.Serialize(stream, cust);
            }
            stream.Close();
        }

        /// <summary>
        /// Method to read and deserialize all the customers from a saved file,
        /// add them to a list and then return the list to the caller
        /// (in our case the CustomerManager)
        /// </summary>
        /// <returns>A list containing all the saved customers</returns>
        public List<Customer> DeserializeCustomers()
        {
            // Local variables
            List<Customer> list = new List<Customer>();
            Customer cust;

            try
            {
                stream = File.Open("CustomersInfo.info", FileMode.Open);
            }
            catch (FileNotFoundException)
            {
                stream = File.Open("CustomersInfo.info", FileMode.Create);
            }

            while ((cust = DeserializeCustomer(stream, binFor)) != null)
            {
                list.Add(cust);
            }
            stream.Close();

            return list;
        }


        /// <summary>
        /// Private method to read and deserialize a customer from a stream.
        /// Broken out since it needed a try/catch clause since
        /// it will crash if we try to read from an empty stream
        /// (it will throw a ArgumentNullException). It looks nicer to have it as a private
        /// method then to have yet another try/catch block in the DeserializeCustomers
        /// method
        /// </summary>
        /// <param name="st">The stream to read from</param>
        /// <param name="bf">The binaryformatter used to deserialize the customer</param>
        /// <returns>A deserialized Customer</returns>
        private Customer DeserializeCustomer(Stream st, BinaryFormatter bf)
        {
            try
            {
                Customer cust = (Customer)bf.Deserialize(stream);
                return cust;
            }
            catch (Exception)
            {
                return null;
            }
        }
    }
}
